//
// errorhandler.h
// libprotea
// Tools Library for the Protea Project / Functionality for handling errors and exceptions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#ifndef __PROTEA_ERRORHANDLER_H__
#define __PROTEA_ERRORHANDLER_H__

#include "OSDep/misc.h"

//
// Tools error handling class
//
extern char errloc[ MAX_PATH ];
const int USER_ERROR_NUMBER	=	-1;



// Forward class declarations
class XCField;

// Functions to support language codes
__EXPORT long XCGetLanguage();
__EXPORT void XCSetLanguage( long value );


/// Define a tools error function
class __EXPORT XCToolsException : public XCBase {
	friend class XCAppInterface;

public:
	XCToolsException( int number, int field, int order, int line=0 );
	XCToolsException( int number, char* descr, int field, int order, int line=0 );
	XCToolsException( const XCToolsException& );
	virtual ~XCToolsException();

	int GetErrorNumber();
	int GetLineNumber();

	void ClearLine();

	void SetOrder( int new_order );
	int GetOrder();
	int GetField();

	char* GetDescription();

	void OutputCallStack( XCAppInterface* app );

	void Clear();

protected:
	virtual void MakeDescr( XCAppInterface* app );

	int line;
	int field;
	int order;
	int errnum;
	int usererrnum;
	char* description;
};



// Tools warning function:  Currently used in conversion.cpp
class __EXPORT XCToolsWarning : public XCToolsException {
public:
	XCToolsWarning( int number ) : XCToolsException( number, 0, 0 ) {};
	XCToolsWarning( int number, char* descr ) : XCToolsException( number, descr, 0, 0 ) {};
};




/// Generic tools exception
class __EXPORT XCToolsError : public XCToolsException {
public:
	friend class XCAppErrorHandler;
	friend class XCAppInterface;

	/// Constructor
	XCToolsError( int number, int line, XCAppInterface* app, int field, int order, int count, ... );

	/// Copy constructor
	XCToolsError( const XCToolsError& );

	ERRHANDLER_SEH_INIT;

	/// Destructor
	virtual ~XCToolsError();

	XCToolsError* Copy() const;

protected:
	XCToolsError( int number, int field, int order );
	void AddParm( void* param );
	virtual void MakeDescr( XCAppInterface* app );

private:
	void* parms[5];
	int parmcount;
};

#define OUTPUTRAISE { if (TOOLSAPP) TOOLSAPP->ToolsTrace( TRC_FUNCTIONS, TLV_LOW, "***** EXCEPTION RAISED *****\n\tfile=%s\n\tline=%d", __FILE__, __LINE__ ); }

#define RAISETOOLSERROR( x ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, 0, 0, 0 ); }
#define RAISETOOLSERROR_1PARAM( x, y ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, 0, 0, 1, y ); }
#define RAISETOOLSERROR_2PARAM( x, y, z ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, 0, 0, 2, y, z ); }
#define RAISETOOLSERROR_3PARAM( x, y, z, a ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, 0, 0, 3, y, z, a ); }
#define RAISETOOLSERROR_4PARAM( x, y, z, w, a ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, 0, 0, 4, y, z, w, a ); }

#define RAISEFIELDERROR( x, field ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, field, 0, 0 ); }
#define RAISEFIELDERROR_1PARAM( x, field, y ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, field, 0, 1, y ); }
#define RAISEFIELDERROR_2PARAM( x, field, y, z ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, field, 0, 2, y, z ); }
#define RAISEFIELDERROR_3PARAM( x, field, y, z, a ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, field, 0, 3, y, z, a ); }
#define RAISEFIELDERROR_4PARAM( x, field, y, z, w, a ) { OUTPUTRAISE; throw XCToolsError( x, __LINE__, TOOLSAPP, field, 0, 4, y, z, w, a ); }

extern bool InErrorState;

#endif
